Design Ride Hailing Service like Uber

Last Updated: December 19, 2025

Ashish

Ashish Pratap Singh

hard

In this chapter, we will explore the low-level design of a simplified ride-sharing platform.

Let's start by clarifying the requirements:

1. Clarifying Requirements

Before starting the design, it's important to ask thoughtful questions to uncover hidden assumptions, clarify ambiguities, and define the system's scope more precisely.

Here is an example of how a conversation between the candidate and the interviewer might unfold:

After gathering the details, we can summarize the key system requirements.

1.1 Functional Requirements

  • Allow riders to request a ride by specifying pickup and drop-off locations and preferred ride type.
  • Notify drivers of incoming ride requests and allow them to accept or reject the request.
  • Allow drivers to start and end a trip once accepted.
  • Update and maintain trip status throughout its lifecycle. Notify riders of trip status changes.
  • Maintain trip history for both riders and drivers

1.2 Non-Functional Requirements

  • Modularity: The system should follow object-oriented principles with well-defined components.
  • Extensibility: The design should be flexible enough to support future enhancements.
  • Maintainability: Code should be clean, modular, and testable, making it easy to debug, refactor, and extend

2. Identifying Core Entities

Core entities are the fundamental building blocks of our system. We identify them by analyzing key nouns (e.g., rider, driver, trip, location, vehicle) and actions (e.g., request, match, track, rate, update) from the functional requirements. These typically translate directly into classes, enums, or interfaces in an object-oriented design.

Below, we break down the functional requirements and extract the relevant entities. Related requirements are grouped together when they represent the same conceptual domain.

1. Riders should be able to request a ride with pickup, drop-off, and ride type.

This introduces several entities:

  • Rider: Represents a user who requests rides. A rider can initiate new trips and view past trip history.
  • Location: Represents a point on the map (latitude, longitude) and is used to calculate distances between users and drivers.
  • RideType (enum): Enum to represent types of rides (e.g., SEDAN, SUV, AUTO).

2. Notify nearby drivers of incoming ride requests, and allow them to accept/reject the request.

This introduces:

  • Driver: Represents a service provider who can accept ride requests. Tracks attributes like current location, availability status, and assigned vehicle.
  • Vehicle: Represents the driver’s car or auto. Includes metadata such as license plate, vehicle type, and capacity.
  • DriverStatus (enum): Indicates whether a driver is ONLINE, IN_TRIP, or OFFLINE.

3. The system must manage and update trip status as it progresses.

This introduces:

  • Trip: Represents an actual ride that connects a rider and a driver. It evolves through various stages and holds information such as start/end times, route, and fare (if needed).
  • TripStatus (enum): Represents the lifecycle of a trip—e.g., REQUESTED, ACCEPTED, IN_PROGRESS, COMPLETED, CANCELLED.

4. System-wide coordination is needed to manage ride requests and driver assignments.

This requires an orchestrator:

  • RideSharingService: A central component responsible for handling ride requests, matching riders with available drivers, managing trip lifecycle, and updating system state.

These core entities define the essential abstractions of the ride-hailing platform and will guide the structure of your low-level design and class diagrams.

3. Designing Classes and Relationships

This section breaks down the system's architecture into its fundamental classes, their responsibilities, and the relationships that connect them. We also explore the key design patterns that provide robustness and flexibility to the solution.

3.1 Class Definitions

The system is composed of several types of classes, each with a distinct role.

Enums

Enums
  • RideType: Defines the categories of vehicles available (e.g., SEDAN, SUV).
  • DriverStatus: Represents the real-time status of a driver (ONLINE, IN_TRIP, OFFLINE).
  • TripStatus: Captures the various stages of a ride's lifecycle (REQUESTED, ASSIGNED, COMPLETED).

Data Classes

Location

A data class holding geographic coordinates.

Location

It includes a utility method to calculate distances, which is fundamental for matching drivers and calculating fares.

Vehicle

Vehicle

Represents a driver's vehicle, containing details like licenseNumber, model, and RideType.

Core Classes

User (Abstract Class)

User

A base class for Rider and Driver, holding common properties like ID, name, and trip history. It implements TripObserver.

  • Rider & Driver: Concrete user classes. They act as Observers to receive trip updates. The Driver class also manages their Vehicle, current Location, and DriverStatus.

Trip

The central entity representing a single ride from request to completion.

Trip

It acts as the Context for the State pattern (delegating actions to its currentState object) and the Subject for the Observer pattern (notifying observers of status changes). Its construction is handled by a nested TripBuilder.

RideSharingService (Singleton & Facade)

The main entry point for all client interactions.

RideSharingService

It orchestrates the entire ride-hailing process, from registering users and handling requests to assigning drivers and processing t

3.2 Class Relationships

The relationships between classes define the system's structure and data flow.

Composition

  • RideSharingService "has-a" collection of Riders, Drivers, and Trips, managing their lifecycle within the system.
  • A Driver "has-a" Vehicle.

Association

  • A Trip is associated with one Rider and one Driver.
  • RideSharingService is associated with a PricingStrategy and a DriverMatchingStrategy to perform its core logic.
  • A Trip is associated with a single TripState at any given time.
  • A Trip (Subject) is associated with multiple TripObservers (Rider and Driver).

Inheritance

  • Rider and Driver inherit from the abstract User class.
  • The concrete state classes (RequestedState, etc.) implement the TripState interface.
  • The concrete strategy classes (NearestDriverMatchingStrategy, etc.) implement their respective strategy interfaces.

Dependency

  • The RideSharingService depends on the strategy interfaces to remain decoupled from specific algorithms.
  • The Trip class uses the TripBuilder class for its instantiation.
  • The client (RideSharingServiceDemo) depends on the RideSharingService facade.

3.3 Key Design Patterns

Facade Pattern

The RideSharingService class serves as a facade. It provides a simple, high-level API (requestRide, acceptRide, endTrip) that hides the complex internal workflows involving state transitions, driver matching, pricing, and notifications.

Singleton Pattern

RideSharingService is implemented as a singleton to ensure there is only one instance coordinating the entire system. This provides a single, global point of access and control.

Strategy Pattern

This pattern is used to make core algorithms interchangeable and extensible.

Driver Matching

DriverMatchingStrategy

DriverMatchingStrategy allows the system to easily switch between different methods for finding drivers (e.g., nearest, highest-rated, least busy)

Pricing

PricingStrategy

PricingStrategy allows the fare calculation logic to be changed dynamically (e.g., flat rate, vehicle-based, surge pricing).

State Pattern

TripState

The lifecycle of a Trip is managed using the State pattern. The Trip (Context) delegates state-specific behavior to its current TripState object. This avoids large conditional blocks and makes adding new states (e.g., CancelledState) easier.

Observer Pattern

TripObserver

This pattern facilitates real-time communication. The Trip (Subject) automatically notifies the Rider and Driver (Observers) whenever its status changes, ensuring all parties are kept up-to-date.

Builder Pattern

The Trip.TripBuilder is used for the complex construction of a Trip object. It ensures that a trip is only created with all the necessary information (rider, locations, fare), improving immutability and robustness.

3.4 Full Class Diagram

Ride Hailing Service Class Diagram

4. Implementation

4.1 Enums

1class RideType(Enum):
2    SEDAN = "SEDAN"
3    SUV = "SUV"
4    AUTO = "AUTO"
5
6class TripStatus(Enum):
7    REQUESTED = "REQUESTED"
8    ASSIGNED = "ASSIGNED"
9    IN_PROGRESS = "IN_PROGRESS"
10    COMPLETED = "COMPLETED"
11    CANCELLED = "CANCELLED"
12
13class DriverStatus(Enum):
14    OFFLINE = "OFFLINE"
15    ONLINE = "ONLINE"
16    IN_TRIP = "IN_TRIP"

These enums capture essential classifications and states for vehicles, drivers, and trip progress.

4.2 Location

Represents a geographic coordinate and computes Euclidean distance for simplicity.

1class Location:
2    def __init__(self, latitude: float, longitude: float):
3        self._latitude = latitude
4        self._longitude = longitude
5    
6    def distance_to(self, other: 'Location') -> float:
7        dx = self._latitude - other._latitude
8        dy = self._longitude - other._longitude
9        return math.sqrt(dx * dx + dy * dy)  # Euclidean for simplicity
10    
11    def __str__(self) -> str:
12        return f"Location({self._latitude}, {self._longitude})"

4.3 Vehicle

Encapsulates vehicle identity and classification, used for fare calculation and filtering compatible rides.

1class Vehicle:
2    def __init__(self, license_number: str, model: str, vehicle_type: RideType):
3        self._license_number = license_number
4        self._model = model
5        self._type = vehicle_type
6    
7    def get_license_number(self) -> str:
8        return self._license_number
9    
10    def get_model(self) -> str:
11        return self._model
12    
13    def get_type(self) -> RideType:
14        return self._type

TripObserver

1class TripObserver(ABC):
2    @abstractmethod
3    def on_update(self, trip: 'Trip'):
4        pass

4.4 Users: Rider & Driver (Observer Pattern)

User

An abstract User class provides a common base for Rider and Driver, reducing code duplication for shared attributes like id, name, and tripHistory

1class User(TripObserver):
2    def __init__(self, name: str, contact: str):
3        self._id = str(uuid.uuid4())
4        self._name = name
5        self._contact = contact
6        self._trip_history: List['Trip'] = []
7    
8    def add_trip_to_history(self, trip: 'Trip'):
9        self._trip_history.append(trip)
10    
11    def get_trip_history(self) -> List['Trip']:
12        return self._trip_history
13    
14    def get_id(self) -> str:
15        return self._id
16    
17    def get_name(self) -> str:
18        return self._name
19    
20    def get_contact(self) -> str:
21        return self._contact

Rider

1class Rider(User):
2    def __init__(self, name: str, contact: str):
3        super().__init__(name, contact)
4    
5    def on_update(self, trip: 'Trip'):
6        print(f"--- Notification for Rider {self.get_name()} ---")
7        print(f"  Trip {trip.get_id()} is now {trip.get_status().value}.")
8        if trip.get_driver() is not None:
9            print(f"  Driver: {trip.get_driver().get_name()} in a {trip.get_driver().get_vehicle().get_model()} "
10                  f"({trip.get_driver().get_vehicle().get_license_number()})")
11        print("--------------------------------\n")

Driver

1class Driver(User):
2    def __init__(self, name: str, contact: str, vehicle: Vehicle, initial_location: Location):
3        super().__init__(name, contact)
4        self._vehicle = vehicle
5        self._current_location = initial_location
6        self._status = DriverStatus.OFFLINE  # Default status
7    
8    def get_vehicle(self) -> Vehicle:
9        return self._vehicle
10    
11    def get_status(self) -> DriverStatus:
12        return self._status
13    
14    def set_status(self, status: DriverStatus):
15        self._status = status
16        print(f"Driver {self.get_name()} is now {status.value}")
17    
18    def get_current_location(self) -> Location:
19        return self._current_location
20    
21    def set_current_location(self, current_location: Location):
22        self._current_location = current_location
23    
24    def on_update(self, trip: 'Trip'):
25        print(f"--- Notification for Driver {self.get_name()} ---")
26        print(f"  Trip {trip.get_id()} status: {trip.get_status().value}.")
27        if trip.get_status() == TripStatus.REQUESTED:
28            print("  A new ride is available for you to accept.")
29        print("--------------------------------\n")

Both Rider and Driver implement the TripObserver interface. This is a key design choice that allows them to be "subscribed" to a Trip and receive real-time status updates via the onUpdate() method.

4.5 TripState (State Pattern)

Implements the State Pattern to encapsulate transitions between various stages of a ride:

  • Requested → Assigned → InProgress → Completed
1class TripState(ABC):
2    @abstractmethod
3    def request(self, trip: 'Trip'):
4        pass
5    
6    @abstractmethod
7    def assign(self, trip: 'Trip', driver: Driver):
8        pass
9    
10    @abstractmethod
11    def start(self, trip: 'Trip'):
12        pass
13    
14    @abstractmethod
15    def end(self, trip: 'Trip'):
16        pass
17
18
19class RequestedState(TripState):
20    def request(self, trip: 'Trip'):
21        print("Trip is already in requested state.")
22    
23    def assign(self, trip: 'Trip', driver: Driver):
24        trip.set_driver(driver)
25        trip.set_status(TripStatus.ASSIGNED)
26        trip.set_state(AssignedState())
27    
28    def start(self, trip: 'Trip'):
29        print("Cannot start a trip that has not been assigned a driver.")
30    
31    def end(self, trip: 'Trip'):
32        print("Cannot end a trip that has not been assigned a driver.")
33
34
35class AssignedState(TripState):
36    def request(self, trip: 'Trip'):
37        print("Trip has already been requested and assigned.")
38    
39    def assign(self, trip: 'Trip', driver: Driver):
40        print("Trip is already assigned. To re-assign, cancel first.")
41    
42    def start(self, trip: 'Trip'):
43        trip.set_status(TripStatus.IN_PROGRESS)
44        trip.set_state(InProgressState())
45    
46    def end(self, trip: 'Trip'):
47        print("Cannot end a trip that has not started.")
48
49
50class InProgressState(TripState):
51    def request(self, trip: 'Trip'):
52        print("Trip is already in progress.")
53    
54    def assign(self, trip: 'Trip', driver: Driver):
55        print("Cannot assign a new driver while trip is in progress.")
56    
57    def start(self, trip: 'Trip'):
58        print("Trip is already in progress.")
59    
60    def end(self, trip: 'Trip'):
61        trip.set_status(TripStatus.COMPLETED)
62        trip.set_state(CompletedState())
63
64
65class CompletedState(TripState):
66    def request(self, trip: 'Trip'):
67        print("Cannot request a trip that is already completed.")
68    
69    def assign(self, trip: 'Trip', driver: Driver):
70        print("Cannot assign a driver to a completed trip.")
71    
72    def start(self, trip: 'Trip'):
73        print("Cannot start a completed trip.")
74    
75    def end(self, trip: 'Trip'):
76        print("Trip is already completed.")

4.6 Trip

Encapsulates the lifecycle and behavior of a single ride.

1class Trip:
2    def __init__(self, builder: 'TripBuilder'):
3        self._id = builder._id
4        self._rider = builder._rider
5        self._driver: Optional[Driver] = None
6        self._pickup_location = builder._pickup_location
7        self._dropoff_location = builder._dropoff_location
8        self._fare = builder._fare
9        self._status = TripStatus.REQUESTED
10        self._current_state = RequestedState()  # Initial state
11        self._observers: List[TripObserver] = []
12    
13    def add_observer(self, observer: TripObserver):
14        self._observers.append(observer)
15    
16    def _notify_observers(self):
17        for observer in self._observers:
18            observer.on_update(self)
19    
20    def assign_driver(self, driver: Driver):
21        self._current_state.assign(self, driver)
22        self.add_observer(driver)
23        self._notify_observers()
24    
25    def start_trip(self):
26        self._current_state.start(self)
27        self._notify_observers()
28    
29    def end_trip(self):
30        self._current_state.end(self)
31        self._notify_observers()
32    
33    # Getters
34    def get_id(self) -> str:
35        return self._id
36    
37    def get_rider(self) -> Rider:
38        return self._rider
39    
40    def get_driver(self) -> Optional[Driver]:
41        return self._driver
42    
43    def get_pickup_location(self) -> Location:
44        return self._pickup_location
45    
46    def get_dropoff_location(self) -> Location:
47        return self._dropoff_location
48    
49    def get_fare(self) -> float:
50        return self._fare
51    
52    def get_status(self) -> TripStatus:
53        return self._status
54    
55    # Setters are protected, only to be called by State objects
56    def set_state(self, state: TripState):
57        self._current_state = state
58    
59    def set_status(self, status: TripStatus):
60        self._status = status
61    
62    def set_driver(self, driver: Driver):
63        self._driver = driver
64    
65    def __str__(self) -> str:
66        return f"Trip [id={self._id}, status={self._status.value}, fare=${self._fare:.2f}]"
67    
68    # Builder Pattern
69    class TripBuilder:
70        def __init__(self):
71            self._id = str(uuid.uuid4())
72            self._rider: Optional[Rider] = None
73            self._pickup_location: Optional[Location] = None
74            self._dropoff_location: Optional[Location] = None
75            self._fare = 0.0
76        
77        def with_rider(self, rider: Rider) -> 'Trip.TripBuilder':
78            self._rider = rider
79            return self
80        
81        def with_pickup_location(self, pickup_location: Location) -> 'Trip.TripBuilder':
82            self._pickup_location = pickup_location
83            return self
84        
85        def with_dropoff_location(self, dropoff_location: Location) -> 'Trip.TripBuilder':
86            self._dropoff_location = dropoff_location
87            return self
88        
89        def with_fare(self, fare: float) -> 'Trip.TripBuilder':
90            self._fare = fare
91            return self
92        
93        def build(self) -> 'Trip':
94            # Basic validation
95            if self._rider is None or self._pickup_location is None or self._dropoff_location is None:
96                raise ValueError("Rider, pickup, and dropoff locations are required to build a trip.")
97            return Trip(self)
  • Uses Builder Pattern for creation.
  • Uses State Pattern for managing trip transitions.
  • Uses Observer Pattern to notify driver and rider on state changes.

4.7 DriverMatchingStrategy (Strategy Pattern)

Implements Strategy Pattern to enable multiple matching algorithms.

1class DriverMatchingStrategy(ABC):
2    @abstractmethod
3    def find_drivers(self, all_drivers: List[Driver], pickup_location: Location, ride_type: RideType) -> List[Driver]:
4        pass
5
6class NearestDriverMatchingStrategy(DriverMatchingStrategy):
7    MAX_DISTANCE_KM = 5.0  # Max distance to consider a driver "nearby"
8    
9    def find_drivers(self, all_drivers: List[Driver], pickup_location: Location, ride_type: RideType) -> List[Driver]:
10        print(f"Finding nearest drivers for ride type: {ride_type.value}")
11        available_drivers = [
12            driver for driver in all_drivers
13            if (driver.get_status() == DriverStatus.ONLINE and
14                driver.get_vehicle().get_type() == ride_type and
15                pickup_location.distance_to(driver.get_current_location()) <= self.MAX_DISTANCE_KM)
16        ]
17        
18        # Sort by distance
19        available_drivers.sort(key=lambda d: pickup_location.distance_to(d.get_current_location()))
20        return available_drivers

4.8 PricingStrategy (Strategy Pattern)

Encapsulates dynamic pricing logic using the Strategy Pattern. Strategies can vary based on vehicle type or flat distance.

1class PricingStrategy(ABC):
2    @abstractmethod
3    def calculate_fare(self, pickup: Location, dropoff: Location, ride_type: RideType) -> float:
4        pass
5
6class FlatRatePricingStrategy(PricingStrategy):
7    BASE_FARE = 5.0
8    FLAT_RATE = 1.5
9    
10    def calculate_fare(self, pickup: Location, dropoff: Location, ride_type: RideType) -> float:
11        distance = pickup.distance_to(dropoff)
12        return self.BASE_FARE + distance * self.FLAT_RATE
13
14class VehicleBasedPricingStrategy(PricingStrategy):
15    BASE_FARE = 2.50
16    RATE_PER_KM = {
17        RideType.SEDAN: 1.50,
18        RideType.SUV: 2.00,
19        RideType.AUTO: 1.00
20    }
21    
22    def calculate_fare(self, pickup: Location, dropoff: Location, ride_type: RideType) -> float:
23        return self.BASE_FARE + self.RATE_PER_KM[ride_type] * pickup.distance_to(dropoff)

4.9 RideSharingService (Singleton + Facade)

Acts as the central coordinator. This class is a Singleton that provides a simplified, high-level API to the entire complex subsystem.

1class RideSharingService:
2    _instance = None
3    _lock = threading.Lock()
4    
5    def __new__(cls):
6        if cls._instance is None:
7            with cls._lock:
8                if cls._instance is None:
9                    cls._instance = super().__new__(cls)
10                    cls._instance._initialized = False
11        return cls._instance
12    
13    def __init__(self):
14        if not self._initialized:
15            self._riders: Dict[str, Rider] = {}
16            self._drivers: Dict[str, Driver] = {}
17            self._trips: Dict[str, Trip] = {}
18            self._pricing_strategy: Optional[PricingStrategy] = None
19            self._driver_matching_strategy: Optional[DriverMatchingStrategy] = None
20            self._initialized = True
21    
22    @classmethod
23    def get_instance(cls):
24        return cls()
25    
26    # Allow changing strategies at runtime for extensibility
27    def set_pricing_strategy(self, pricing_strategy: PricingStrategy):
28        self._pricing_strategy = pricing_strategy
29    
30    def set_driver_matching_strategy(self, driver_matching_strategy: DriverMatchingStrategy):
31        self._driver_matching_strategy = driver_matching_strategy
32    
33    def register_rider(self, name: str, contact: str) -> Rider:
34        rider = Rider(name, contact)
35        self._riders[rider.get_id()] = rider
36        return rider
37    
38    def register_driver(self, name: str, contact: str, vehicle: Vehicle, initial_location: Location) -> Driver:
39        driver = Driver(name, contact, vehicle, initial_location)
40        self._drivers[driver.get_id()] = driver
41        return driver
42    
43    def request_ride(self, rider_id: str, pickup: Location, dropoff: Location, ride_type: RideType) -> Optional[Trip]:
44        rider = self._riders.get(rider_id)
45        if rider is None:
46            raise KeyError("Rider not found")
47        
48        print(f"\n--- New Ride Request from {rider.get_name()} ---")
49        
50        # 1. Find available drivers
51        available_drivers = self._driver_matching_strategy.find_drivers(
52            list(self._drivers.values()), pickup, ride_type
53        )
54        
55        if not available_drivers:
56            print("No drivers available for your request. Please try again later.")
57            return None
58        
59        print(f"Found {len(available_drivers)} available driver(s).")
60        
61        # 2. Calculate fare
62        fare = self._pricing_strategy.calculate_fare(pickup, dropoff, ride_type)
63        print(f"Estimated fare: ${fare:.2f}")
64        
65        # 3. Create a trip using the Builder
66        trip = Trip.TripBuilder() \
67            .with_rider(rider) \
68            .with_pickup_location(pickup) \
69            .with_dropoff_location(dropoff) \
70            .with_fare(fare) \
71            .build()
72        
73        self._trips[trip.get_id()] = trip
74        
75        # 4. Notify nearby drivers (in a real system, this would be a push notification)
76        print("Notifying nearby drivers of the new ride request...")
77        for driver in available_drivers:
78            print(f" > Notifying {driver.get_name()} at {driver.get_current_location()}")
79            driver.on_update(trip)
80        
81        return trip
82    
83    def accept_ride(self, driver_id: str, trip_id: str):
84        driver = self._drivers.get(driver_id)
85        trip = self._trips.get(trip_id)
86        if driver is None or trip is None:
87            raise KeyError("Driver or Trip not found")
88        
89        print(f"\n--- Driver {driver.get_name()} accepted the ride ---")
90        
91        driver.set_status(DriverStatus.IN_TRIP)
92        trip.assign_driver(driver)
93    
94    def start_trip(self, trip_id: str):
95        trip = self._trips.get(trip_id)
96        if trip is None:
97            raise KeyError("Trip not found")
98        print(f"\n--- Trip {trip.get_id()} is starting ---")
99        trip.start_trip()
100    
101    def end_trip(self, trip_id: str):
102        trip = self._trips.get(trip_id)
103        if trip is None:
104            raise KeyError("Trip not found")
105        print(f"\n--- Trip {trip.get_id()} is ending ---")
106        trip.end_trip()
107        
108        # Update statuses and history
109        driver = trip.get_driver()
110        driver.set_status(DriverStatus.ONLINE)  # Driver is available again
111        driver.set_current_location(trip.get_dropoff_location())  # Update driver location
112        
113        rider = trip.get_rider()
114        driver.add_trip_to_history(trip)
115        rider.add_trip_to_history(trip)
116        
117        print(f"Driver {driver.get_name()} is now back online at {driver.get_current_location()}")
  • Uses Singleton Pattern for global access.
  • Implements Facade Pattern to abstract complex workflows like ride creation, driver assignment, and trip state transitions.

4.10 RideSharingServiceDemo

The demo class validates the end-to-end functionality by simulating a rider requesting and completing a trip.

1class RideSharingServiceDemo:
2    @staticmethod
3    def main():
4        # 1. Setup the system using singleton instance
5        service = RideSharingService.get_instance()
6        service.set_driver_matching_strategy(NearestDriverMatchingStrategy())
7        service.set_pricing_strategy(VehicleBasedPricingStrategy())
8        
9        # 2. Register riders and drivers
10        alice = service.register_rider("Alice", "123-456-7890")
11        
12        bob = service.register_driver("Bob",
13                                    "243-987-2860",
14                                    Vehicle("KA01-1234", "Toyota Prius", RideType.SEDAN),
15                                    Location(1.0, 1.0))
16        
17        charlie = service.register_driver("Charlie",
18                                        "313-486-2691",
19                                        Vehicle("KA02-5678", "Honda CRV", RideType.SUV),
20                                        Location(2.0, 2.0))
21        
22        david = service.register_driver("David",
23                                      "613-586-3241",
24                                      Vehicle("KA03-9012", "Honda CRV", RideType.SEDAN),
25                                      Location(1.2, 1.2))
26        
27        # 3. Drivers go online
28        bob.set_status(DriverStatus.ONLINE)
29        charlie.set_status(DriverStatus.ONLINE)
30        david.set_status(DriverStatus.ONLINE)
31        
32        # David is online but will be too far for the first request
33        david.set_current_location(Location(10.0, 10.0))
34        
35        # 4. Alice requests a ride
36        pickup_location = Location(0.0, 0.0)
37        dropoff_location = Location(5.0, 5.0)
38        
39        # Rider wants a SEDAN
40        trip1 = service.request_ride(alice.get_id(), pickup_location, dropoff_location, RideType.SEDAN)
41        
42        if trip1 is not None:
43            # 5. One of the nearby drivers accepts the ride
44            # In this case, Bob (1.0, 1.0) is closer than David (10.0, 10.0 is too far).
45            # Charlie is ignored because he drives an SUV.
46            service.accept_ride(bob.get_id(), trip1.get_id())
47            
48            # 6. The trip progresses
49            service.start_trip(trip1.get_id())
50            service.end_trip(trip1.get_id())
51        
52        print("\n--- Checking Trip History ---")
53        print(f"Alice's trip history: {alice.get_trip_history()}")
54        print(f"Bob's trip history: {bob.get_trip_history()}")
55        
56        # --- Second ride request ---
57        print("\n=============================================")
58        harry = service.register_rider("Harry", "167-342-7834")
59        
60        # Harry requests an SUV
61        trip2 = service.request_ride(harry.get_id(),
62                                    Location(2.5, 2.5),
63                                    Location(8.0, 8.0),
64                                    RideType.SUV)
65        
66        if trip2 is not None:
67            # Only Charlie is available for an SUV ride
68            service.accept_ride(charlie.get_id(), trip2.get_id())
69            service.start_trip(trip2.get_id())
70            service.end_trip(trip2.get_id())
71
72if __name__ == "__main__":
73    RideSharingServiceDemo.main()

5. Run and Test

Files22
core
entities
enums
observer
states
strategies
ride_sharing_service_demo.py
main
ride_sharing_service.py
ride_sharing_service_demo.pymain
Output

6. Quiz

Design Ride Hailing Service - Quiz

1 / 19
Multiple Choice

Which entity is responsible for coordinating ride requests and driver assignments in a ride-sharing system?

How helpful was this article?

Comments


0/2000

No comments yet. Be the first to comment!

Copilot extension content script